
const httpProxy = require('http-proxy');
const zlib = require('zlib');


function processZip(content, encoding) {
    if (!encoding) {
        return content;
    }
    let decodeMethod = '';
    let encodeMethod = '';

    switch (encoding) {
        case 'gzip':
            decodeMethod = 'gunzipSync';
            encodeMethod = 'gzipSync';
            break;
        case 'deflate':
            decodeMethod = 'inflateSync';
            encodeMethod = 'deflateSync';
            break;
        case 'br':
            decodeMethod = 'brotliDecompressSync';
            encodeMethod = 'brotliCompressSync';
            break;
        default:
            break;
    }

    return zlib[decodeMethod](content);
}
// 创建代理服务器
const proxyFun = (req, res, options) => {
    return new Promise((resolve, reject) => {
        const proxy = httpProxy.createProxyServer();
        let pathRewrite = options.pathRewrite;
        delete options['pathRewrite'];

        if (pathRewrite) {
            let url = req.url;
            Object.keys(pathRewrite).forEach((key) => {
                url = url.replace(new RegExp(key), pathRewrite[key]);
            });

            req.url = url;
        };

        proxy.web(req, res, {
            ...options
        });

        proxy.on('proxyReq', function(req) {
            console.log('转发请求：', req.path);
        });
    
        proxy.on('proxyRes', function(res) {
            let data = [];

            res.on('data', (chunk) => { 
                data.push(chunk);
            });
            res.on('end', () => {
                let str = processZip(Buffer.concat(data), res.headers['content-encoding']);

                resolve({
                    res: res,
                    data: str instanceof Buffer ? str.toString() : str
                });
                proxy.close();
            });

            res.on('error', (err) => {
                console.error(err);
            })
        });

        proxy.on('error', (err) => {
            console.log(err);
        });
    });
}

module.exports = (config, utils) => {
    return async (ctx, next) => {
        const proxyConfig = config.proxy;
        const url = ctx.path;
        
        let targetOption = null;

        if (proxyConfig[url]) {
            targetOption = proxyConfig[url];
        }
        else {
            Object.keys(proxyConfig).forEach((key) => {
                if (url.indexOf(key) === 0) {
                    targetOption = proxyConfig[key]
                }
            });
        }

        if(targetOption) {
            const {res, data} = await proxyFun(ctx.req, ctx.res, {...targetOption});

            ctx.status = res.statusCode;
            ctx.body = data;
        }
        else {
            await next();
        }
    }
}